 /* 
 * File:   cLateralPlayer.cpp
 * Author: josep
 * 
 * Created on 24 / desembre / 2010, 01:00
 */

#include "cLateralPlayer.h"
#include "cCollisionEvent.h"
#include "cItemCollisionEvent.h"
#include "cItem.h"

cLateralPlayer::cLateralPlayer():cLateralAgent() {
    MaxJumpForce=MAX_JUMP;
    JumpForce=0;
    ObjetctType=PLAYER_TYPE;
    ItemCounter[0]=0;
    ItemCounter[1]=0;
    lives=5;
    Winner=false;
    super=false;
}

cLateralPlayer::cLateralPlayer(const cLateralPlayer& orig):cLateralAgent(orig) {
    MaxJumpForce=orig.MaxJumpForce;
    JumpForce=orig.JumpForce;
    lives=orig.lives;
    enemies=orig.enemies;
    for(int i=0; i<MAX_ITEM_INDEX; i++){
        ItemCounter[i]=orig.ItemCounter[i];
    }
    Winner=orig.Winner;
}

cLateralPlayer::~cLateralPlayer(){

}

int cLateralPlayer::ChangeFramestate(int trans, int oldSt, int newSt){
    if(trans==STOP){
            SetSpeedX(0);
    }else if(trans==TO_RIGHT){
        if(super){
            SetSpeedX(SUPER_GO);
        }else{
            SetSpeedX(GO);
        }
    }else if(trans==TO_LEFT){
        if(super){
            SetSpeedX(-SUPER_GO);
        }else{
            SetSpeedX(-GO);
        }
    }else if(trans==JUMP){
        if(!IsInTheAir()){
            SetForceFactor(Y, 2);
            //JumpForce=0;
        }
    }
    SetFrameState(GetViewState(newSt));

    return State<cLateralAgent>::CONTINUE;
}

void cLateralPlayer::prepareJump(){
    if(JumpForce<MaxJumpForce){
        JumpForce++;
    }else{
        Jump();
    }
}
void cLateralPlayer::SetMaxJumpForce(int MaxJumpForce) {
    this->MaxJumpForce = MaxJumpForce;
}
int cLateralPlayer::GetMaxJumpForce() const {
    return MaxJumpForce;
}
int cLateralPlayer::GetJumpForce() const {
    return JumpForce;
}

void cLateralPlayer::Init(cTexture* texture, int PosX, int PosY, int Width, int Height){
    cLateralAgent::Init(texture, PosX, PosY, Width, Height);
    cLateralPlayer::Init();
}

void cLateralPlayer::Init(){
    FromLogicToViewCorrespondence.resize(6);
    FromLogicToViewCorrespondence[0]=0;
    FromLogicToViewCorrespondence[1]=1;
    FromLogicToViewCorrespondence[2]=4;
    FromLogicToViewCorrespondence[3]=5;
    FromLogicToViewCorrespondence[4]=0;
    FromLogicToViewCorrespondence[5]=1;

   StateMachine<cLateralPlayer> *vSm = new StateMachine<cLateralPlayer>();

    vSm->addState(this);
    vSm->addState(this);
    vSm->addState(this);
    vSm->addState(this);
    vSm->addState(this);
    vSm->addState(this);
    vSm->addState(this);
    vSm->getState(LEFT)->setName("Left");
    vSm->getState(RIGHT)->setName("Rigth");
    vSm->getState(MOVING_LEFT)->setName("Moving to left");
    vSm->getState(MOVING_RIGHT)->setName("Moving to right");
    vSm->getState(JUMPING_LEFT)->setName("Jumping to left");
    vSm->getState(JUMPING_RIGHT)->setName("Jumping to right");
    vSm->getState(DEATH)->setName("Death");

    vSm->getState(LEFT)->setTransition(TO_LEFT, vSm->getState(MOVING_LEFT));
    vSm->getState(LEFT)->setTransition(TO_RIGHT, vSm->getState(MOVING_RIGHT));
    vSm->getState(LEFT)->setTransition(JUMP, vSm->getState(JUMPING_LEFT));
    vSm->getState(LEFT)->setTransition(DIE, vSm->getState(DEATH));

    vSm->getState(RIGHT)->setTransition(TO_LEFT, vSm->getState(MOVING_LEFT));
    vSm->getState(RIGHT)->setTransition(TO_RIGHT, vSm->getState(MOVING_RIGHT));
    vSm->getState(RIGHT)->setTransition(JUMP, vSm->getState(JUMPING_RIGHT));
    vSm->getState(RIGHT)->setTransition(DIE, vSm->getState(DEATH));

    vSm->getState(MOVING_LEFT)->setTransition(STOP, vSm->getState(LEFT));
    vSm->getState(MOVING_LEFT)->setTransition(TO_RIGHT, vSm->getState(MOVING_RIGHT));
    vSm->getState(MOVING_LEFT)->setTransition(JUMP, vSm->getState(JUMPING_LEFT));
    vSm->getState(MOVING_LEFT)->setTransition(DIE, vSm->getState(DEATH));

    vSm->getState(MOVING_RIGHT)->setTransition(STOP, vSm->getState(RIGHT));
    vSm->getState(MOVING_RIGHT)->setTransition(TO_LEFT, vSm->getState(MOVING_LEFT));
    vSm->getState(MOVING_RIGHT)->setTransition(JUMP, vSm->getState(JUMPING_RIGHT));
    vSm->getState(MOVING_RIGHT)->setTransition(DIE, vSm->getState(DEATH));

    vSm->getState(JUMPING_LEFT)->setTransition(STOP_JUMP, vSm->getState(LEFT));
    vSm->getState(JUMPING_LEFT)->setTransition(TO_LEFT, vSm->getState(JUMPING_LEFT));
    vSm->getState(JUMPING_LEFT)->setTransition(TO_RIGHT, vSm->getState(JUMPING_RIGHT));
    vSm->getState(JUMPING_LEFT)->setTransition(DIE, vSm->getState(DEATH));

    vSm->getState(JUMPING_RIGHT)->setTransition(STOP_JUMP, vSm->getState(RIGHT));
    vSm->getState(JUMPING_RIGHT)->setTransition(TO_LEFT, vSm->getState(JUMPING_LEFT));
    vSm->getState(JUMPING_RIGHT)->setTransition(TO_RIGHT, vSm->getState(JUMPING_RIGHT));
    vSm->getState(JUMPING_RIGHT)->setTransition(DIE, vSm->getState(DEATH));

    vSm->getState(DEATH)->setTransition(REVIVE, vSm->getState(RIGHT));

    vSm->getState(LEFT)->addSubscription(State<cLateralPlayer>::SUBSCRIPTION_IN,
                                                    &cLateralPlayer::ChangeFramestate);
    vSm->getState(RIGHT)->addSubscription(State<cLateralPlayer>::SUBSCRIPTION_IN,
                                                    &cLateralPlayer::ChangeFramestate);
    vSm->getState(MOVING_LEFT)->addSubscription(State<cLateralPlayer>::SUBSCRIPTION_IN,
                                                    &cLateralPlayer::ChangeFramestate);
    vSm->getState(MOVING_RIGHT)->addSubscription(State<cLateralPlayer>::SUBSCRIPTION_IN,
                                                    &cLateralPlayer::ChangeFramestate);
    vSm->getState(JUMPING_LEFT)->addSubscription(State<cLateralPlayer>::SUBSCRIPTION_IN,
                                                    &cLateralPlayer::ChangeFramestate);
    vSm->getState(JUMPING_RIGHT)->addSubscription(State<cLateralPlayer>::SUBSCRIPTION_IN,
                                                    &cLateralPlayer::ChangeFramestate);

    vSm->setInitialState(0);

    sm = (StateMachine<cLateralAgent>*) vSm;

    SetSurfaceType(NORTH_SURFACE, NORMAL_SURFACE);
    SetSurfaceType(EAST_SURFACE, NORMAL_SURFACE);
    SetSurfaceType(WEST_SURFACE, NORMAL_SURFACE);
    SetSurfaceType(SOUTH_SURFACE, HARD_SURFACE);

}

bool cLateralPlayer::isDead(){
    return sm->getCurrentState()->getId()==DEATH;
}
void cLateralPlayer::setLives(int lives) {
    this->lives = lives;
}
int cLateralPlayer::getLives() const {
    return lives;
}
void cLateralPlayer::setItemCounter(int ind, int ItemCounter) {
    this->ItemCounter[ind] = ItemCounter;
}
int cLateralPlayer::getItemCounter(int ind) const {
    return ItemCounter[ind];
}
void cLateralPlayer::setEnemies(int enemies) {
    this->enemies = enemies;
}
int cLateralPlayer::getEnemies() const {
    return enemies;
}

bool cLateralPlayer::NotifyAgentCollision(cAgentCollisionEvent* revent){
	bool ret;
    if((ret=cLateralAgent::NotifyAgentCollision(revent))){
        if(IsInTheAir()){
            this->StopY(revent->GetArea()->maxPointY()+1);
            this->SetForceFactor(Y, 3);
            if(!revent->IsDead()){
                this->enemies++;
            }
            ret=false;

        }
    }
	return ret;
}

void cLateralPlayer::Notify(cPhysicalReaction *revent){
    if(revent->GetReactionType()==cPhysicalReaction::ITEM_COLLISION){
        if(IS_ITEM(((cItemCollisionEvent*) revent)->GetItem())){
            cItem* item =(cItem *) ((cItemCollisionEvent*) revent)->GetItem();

            ItemCounter[item->GetObjectIndex()]+=item->GetValue();
            item->Captured();
        }else{
            //TO DO...
        }

    }else{
        cLateralAgent::Notify(revent);
    }
}

void cLateralPlayer::NextStep(int time){
    cLateralAgent::NextStep(time);
    if(isSuper()){
        ItemCounter[FOOD_ITEM_INDEX]-=FOOD_CONSUM;
        if(ItemCounter[FOOD_ITEM_INDEX]<=0){
            ItemCounter[FOOD_ITEM_INDEX]=0;
            setSuper(false);
        }
    }
}



void cLateralPlayer::revive(){
    lives--;
    sm->processTransition(REVIVE);
    SetPosY(PosY+10);
}

bool cLateralPlayer::isWinner(){
    return Winner;
}
void cLateralPlayer::setSuper(bool super) {
    if(!super){
        this->super = super;
        SetSurfaceType(NORTH_SURFACE, NORMAL_SURFACE);
        SetSurfaceType(EAST_SURFACE, NORMAL_SURFACE);
        SetSurfaceType(WEST_SURFACE, NORMAL_SURFACE);
        SetSurfaceType(SOUTH_SURFACE, HARD_SURFACE);
        
    }else  if(super && ItemCounter[FOOD_ITEM_INDEX]>FOOD_CONSUM){
        this->super = super;
        SetSurfaceType(NORTH_SURFACE, BULLLET_SURFACE);
        SetSurfaceType(EAST_SURFACE, BULLLET_SURFACE);
        SetSurfaceType(WEST_SURFACE, BULLLET_SURFACE);
        SetSurfaceType(SOUTH_SURFACE, BULLLET_SURFACE);
    }
}
bool cLateralPlayer::isSuper() const {
    return super;
}
